package com.zheng.study.base.service;

import com.zheng.study.base.bean.search.Search;
import com.zheng.study.base.bean.search.order.Order;
import com.zheng.study.base.bean.search.page.PagePaging;
import com.zheng.study.base.bean.search.result.*;
import com.zheng.study.base.bean.search.rule.Rule;
import com.zheng.study.base.entity.BaseEntity;
import org.hibernate.Query;
import org.hibernate.SQLQuery;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * Service接口 - Service接口基类
 * ============================================================================
 * author : fallenpanda
 * createDate:  2016-07-19 。
 * ============================================================================
 */
public interface BaseService<T extends BaseEntity, PK extends Serializable> {

	/**
	 * 获取实体对象
	 * @param id 记录id
	 * @return 实体对象
	 */
	T load(PK id);

	/**
	 * 根据id获取实体
	 * @param id 记录id
	 * @return 实体对象
	 */
	T get(PK id);

	/**
	 * 向数据库插入一条数据
	 * @param entity 实体类
	 * @return ID
	 */
	PK save(T entity);

	/**
	 * 删除
	 * @param entity 实体对象
	 */
	void delete(T entity);

	/**
	 * 通过id删除
	 * @param id 对象id
	 */
	void delete(PK id);

	/**
	 * 更新
	 * @param entity 实体对象
	 */
	void update(T entity);

	/**
	 * 通过id数组获取对象集合
	 * @param ids id数组
	 * @return 对象集合
	 */
	List<T> get(PK[] ids);

	/**
	 * 通过一个属性名和属性值获取对象集合
	 * @param propertyName 属性名
	 * @param value 属性值
	 * @return 对象集合
	 */
	T get(String propertyName , Object value);

	/**
	 * 根据属性名 修改前后属性值判断在数据库中是否唯一（若新修改的值与原来的值相等则返回true）
	 * @param propertyName 属性名
	 * @param oldValue 修改前的值
	 * @param newValue 修改后的值
	 * @return boolean
	 */
	boolean isUnique(String propertyName, Object oldValue, Object newValue);

	/**
	 * 根据属性名判断数据是否存在
	 * @param propertyName 属性名
	 * @param value 值
	 * @return boolean
	 */
	boolean isExist(String propertyName, Object value);

	/**
	 * 根据属性名和属性值获取对象集合
	 * @param propertyName 属性名
	 * @param value 属性值
	 * @return 对象集合
	 */
	List<T> getList(String propertyName, Object value);

	/**
	 * 获取所有实体对象集合
	 * @return 对象集合
	 */
	List<T> getAll();

	/**
	 *
	 * 获取所有实体对象的总数
	 * @return 对象总数
	 */
	Long getTotalCount();

	/**
	 * 刷新session
	 */
	void flush();

	/**
	 * 清除session
	 */
	void clear();

	/**
	 * 清除某一对象
	 * @param object 要清除的对象
	 */
	void evict(Object object);

	/**
	 * 执行hql语句
	 * @param hql hql语句
	 * @return Query
	 */
	Query createQuery(String hql);

	/**
	 * 执行sql语句
	 * @param sql sql语句
	 * @return SQLQuery
	 */
	SQLQuery createSqlQuery(String sql);

	/**
	 * 得到唯一结果
	 * @param hql  hql语句
	 * @return object
	 */
	Object getUniqueResult(String hql);

	/**
	 * 通过hql获得集合
	 * @param hql hql语句
	 * @return List集合
	 */
	List<T> getList(String hql);

	/**
	 * 根据hql语句和Map集合条件获得唯一结果
	 * @param hql hql语句
	 * @param params 存放查询条件的map集合
	 * @return Object
	 */
	Object getUniqueResult(String hql, Map<String, Object> params);

	/**
	 * 根据hql语句和Map集合条件获得集合
	 * @param hql hql语句
	 * @param params 存放查询条件的map集合
	 * @return List集合
	 */
	List<T> getList(String hql, Map<String, Object> params);

	/**
	 * 获得集合
	 * @param hql hql语句
	 * @param params map集合参数
	 * @return List集合
	 */
	List<Object[]> getObjectList(String hql, Map<String, Object> params);

	/**
	 * 获得集合
	 * @param hql hql语句
	 * @param params map集合参数
	 * @return List集合
	 */
	List<Map<String, Object>> getMapList(String hql, Map<String, Object> params);

	/**
	 * 根据search对象进行查询（提供分页/条件查找/排序功能）
	 * @param search search对象
	 * @return search
	 */
	SearchResult findBySearch(Search search);

	/**
	 * 根据文档id和实体类名来获得实体对象
	 * @param keyId 文档id
	 * @param className 类名
	 * @return object
	 */
	Object getObjectEntity(String keyId, String className);

	/**
	 * 根据条件查询数量
	 * @param rules List<Rule> rules
	 * @return searchResultCount.getCount()
	 */
	SearchResultCount findCountBySearch(List<Rule> rules);

	/**
	 * 根据条件获取唯一的对象
	 * @param rules List<Rule> rules
	 * @return searchResultUnique.getObject()
	 */
	SearchResultUnique findUniqueBySearch(List<Rule> rules);

	/**
	 * 根据条件获取实体类集合
	 * @param rules List<Rule> rules
	 * @param orders 排序
	 * @return searchResultList.getList()
	 */
	SearchResultList findListBySearch(List<Rule> rules, Order... orders);

	/**
	 * 根据条件获取分页数据
	 * @param page 分页
	 * @param rules 条件
	 * @param orders 排序
	 * @return
	 */
	SearchResultPaging findPagingBySearch(PagePaging page, List<Rule> rules, Order... orders);

}
